function util.PaintDown(start, effname, ignore)
   local BoneTrace = {start=start, endpos=(start + Vector(0,0,-256)), filter=ignore, mask=MASK_SOLID}

   local BTrace = util.TraceLine(BoneTrace)
   util.Decal(effname, BTrace.HitPos+BTrace.HitNormal, BTrace.HitPos-BTrace.HitNormal)
end

local function CreateDeathEffect(ent, marked)
	local Effect = EffectData()
	for i = 1, 20 do		
		Effect:SetOrigin( ent:GetPos() )
		Effect:SetEntity( ent )
		util.Effect( "bloodpool1", Effect )
		util.Effect( "bloodpool2", Effect )
	end
end

function UnCorpse(ply)
	ply:UnSpectate()
	ply:SpectateEntity(nil)
	ply:SetNoTarget(false)
	ply:Spawn()
end

hook.Add("PlayerDeath", "CorpseDeath", function(victim, weapon, killer)
   local RagdollEnt = victim.ServerRagdoll
	victim:SpectateEntity(RagdollEnt)
    victim:Spectate(OBS_MODE_CHASE)
    victim:SetNoTarget(true)
end)

hook.Add("PlayerDeath", "SetRespawn", function(ply)
	ply.NextSpawn = CurTime() + 7
end)

hook.Add("PlayerDeathThink", "UnCorpseYourself", function(ply)
	if CurTime()>=ply.NextSpawn then
		UnCorpse(ply)
	end
	return false
end)

local Alpha1

function GM:DoPlayerDeath(ply, attacker, dmginfo)

	for k,v in pairs(ents.GetAll()) do
		if v.UniqueishID == ply:UniqueID() then
			timer.Create(math.random(1,999999)..v:EntIndex(), 0.02, 255, function()
			
			if ValidEntity(v) then
				local r,g,b,a = v:GetColor()
				if a <= 0 then
					v:Remove()
				else
					Alpha1 = math.Approach(a, 0, 0.6)
					v:SetColor(r, g, b, Alpha1)
					end
				end		
			end)
		end
	end
		
	local rag = CreateCorpse(ply, attacker, dmginfo)
	ply.ServerRagdoll = rag
   
	CreateDeathEffect(ply, false)
	ply:AddDeaths( 1 )
   
     if ( attacker:IsValid() && attacker:IsPlayer() ) then
        if ( attacker == ply ) then
            attacker:AddFrags( -1 )
        else
            attacker:AddFrags( 1 )
        end
    end  
end


function CreateCorpse(ply, attacker, dmginfo)

      if not IsValid(ply) then return end

      local rag = ents.Create("prop_ragdoll")
      if not ValidEntity(rag) then return nil end

      rag:SetPos(ply:GetPos())
      rag:SetModel(ply:GetModel())
      rag:SetAngles(ply:GetAngles())
      rag:Spawn()
      rag:Activate()
      rag:SetCollisionGroup(COLLISION_GROUP_DEBRIS_TRIGGER)
      rag.UniqueishID = ply:UniqueID()

      local num = rag:GetPhysicsObjectCount()-1
      local v = ply:GetVelocity() / (num / 2)
      for i=0, num do
         local bone = rag:GetPhysicsObjectNum(i)
         if ValidEntity(bone) then
            local bp, ba = ply:GetBonePosition(rag:TranslatePhysBoneToBone(i))
            if bp and ba then
               bone:SetPos(bp)
               bone:SetAngle(ba)
            end

            bone:SetVelocity(v)

         end
      end


    return rag
end

hook.Add( "PhysgunPickup", "RagdollPickup", function(ply, ent)
	if ent:GetClass() == "prop_ragdoll" and ent.UniqueishID then
		return false
	end
end)

hook.Add( "GravGunPickupAllowed", "RagdollGravPickup", function(ply, ent)
	if ent:GetClass() == "prop_ragdoll" and ent.UniqueishID then
		return false
	end
end)